package qq_bot

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"time"
	chatgpt3_5 "zy_bot_demo/chatgpt3.5"
)

// GroupTask 群消息task
type GroupTask struct {
	GroupId int64  `json:"group_id"`
	UserId  int64  `json:"user_id"`
	Message string `json:"message"`
}

// 每次群里需要访问 chatgpt 时，将请求放入队列，然后多个工作协程开始工作

type Worker struct {
	GroupTaskChan chan GroupTask
}

type GroupTaskHandler interface {
	PutGroupTask(task GroupTask)
	HandleGroupTask(task GroupTask)
}

func NewWorker() *Worker {
	return &Worker{
		GroupTaskChan: make(chan GroupTask, 100),
	}
}

var worker *Worker

func InitWorker() {
	worker = NewWorker()
	go func() {
		for {
			time.Sleep(1 * time.Second)
			select {
			case task, ok := <-worker.GroupTaskChan:
				if !ok {
					println("No messages received... not ok")
				}
				go worker.HandleGroupTask(task)
			default:
				time.Sleep(1 * time.Second)
				println("No messages received...")
			}
		}
	}()
}

func (w *Worker) PutGroupTask(task GroupTask) {
	w.GroupTaskChan <- task
}

// HandleGroupTask 不停的从管道中取数据，然后去处理
func (w *Worker) HandleGroupTask(task GroupTask) {
	defer func() {
		if err := recover(); err != nil {
			fmt.Println(fmt.Sprintf("发生了错误。。。 %v", err))
		}
	}()
	message := task.Message
	//resp, err := SendMessage(message)
	resp, err := chatgpt3_5.SendMessage(message)
	if err != nil {
		panic(err)
		println(err)
	}
	task.Message = resp.Choice[0].Message.Content
	go SendGroupMessage(task)
}

type GroupMessage struct {
	GroupId int64  `json:"group_id"`
	Message string `json:"message"`
}

// SendGroupMessage 发送QQ群消息
func SendGroupMessage(task GroupTask) {
	defer func() {
		if err := recover(); err != nil {
			fmt.Println(fmt.Sprintf("发生了错误。。。 %v", err))
		}
	}()
	sendGroupMsgUrl := "http://127.0.0.1:5700/send_group_msg"
	println(sendGroupMsgUrl)
	message := GroupMessage{
		GroupId: task.GroupId,
		Message: fmt.Sprintf("[CQ:at,qq=%v]", task.UserId) + "\n" + task.Message,
	}
	marshal, _ := json.Marshal(message)

	req, err := http.NewRequest("POST", sendGroupMsgUrl, bytes.NewReader(marshal))
	if err != nil {
		panic(err)
	}
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	println(string(body))
}
